<template>
  <div class="msg">
    <div class="content">
      <div ref="msg" :class="[expand ? 'text-expand': 'text']" v-html="formatMsg" @click="redirect"></div>
      <div class="btn" v-if="enableExpand" @click="toggle">{{ btnText }}</div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'PostMsg',
  inject: ['rootRouter'],
  props: {
    // 动态id
    id: {
      type: [Number, String]
    },
    msg: {
      type: String
    },
    /*
      // at召唤人的格式
      ats: [
        {
          data: 用户id,
          length: 用户名长度,
          location: 用户名位置,
          type: 1 用户: 1 | 抽奖：2 | 投票：3
        }
      ]
    */
    ats: {
      type: Array
    },
    /*
      // emoji图片格式
      emojis: [
        {
          emoji_name: [tv_腼腆],
          text: [tv_腼腆],
          url: '图片地址'
        }
      ]
    */
    emojis: {
      type: Array
    },
    /*
      // 话题数组格式
      topics: [
        {
          is_activity: 1
          topic_id: 7085462
          topic_link: ""
          topic_name: "阅片无数"
        }
      ]
    */
    topics: {
      type: Array
    },
    /*
      // 投票格式
      votes: {
        desc: "投票标题"
        join_num: 参与人数
        vote_id: 投票id
      }
    */
    votes: {
      type: Object,
      default: null
    }
  },
  data () {
    return {
      expand: false,
      enableExpand: false
    }
  },
  computed: {
    urlReg () {
      return /(https?:\/\/(\w+\.)?(bilibili|biligame|acg|b23)\.(com|tv)[/.$*?~=#!%@&\-\w]*)/g
    },
    btnText () {
      return this.expand ? '收起' : '展开'
    },
    formatMsg () {
      let tempMsg = this.msg
      const ats = this.ats
      const topics = this.topics
      const emojis = this.emojis
      // 替换用户|抽奖
      if (ats.length) {
        const users = []
        // 先获取到用户名称
        for (const at of ats) {
          const { data, location, length, type } = at
          let str = ''
          if (type === 1) {
            str = tempMsg.substr(location, length)
          } else if (type === 2 || type === 4) {
            str = tempMsg.substring(location, location + (data - 0))
          }
          users.push({
            name: str,
            id: data,
            type
          })
        }
        let lastUserName = null
        for (const user of users) {
          const { name, id, type } = user
          const userReg = new RegExp(name, 'gm')
          if (type === 1) {
            tempMsg = tempMsg.replace(userReg, `<span class="highlight" data-name="space" data-params="mid" data-value="${id}">${name}</span>`)
          } else if (type === 2) {
            tempMsg = tempMsg.replace(userReg, `<span class="highlight lottery" data-name="lottery" data-params="lid" data-value="${this.id}">${name}</span>`)
          } else if (type === 4) {
            if (lastUserName !== name) {
              tempMsg = tempMsg.replace(userReg, `<span class="highlight" data-name="" data-params="" data-value="">${name}</span>`)
            }
          }
          lastUserName = name
        }
      }
      // 替换话题
      if (topics.length) {
        for (const topic of topics) {
          const name = topic.topic_name
          const tag = `#${name}#`
          const reg = new RegExp(tag, 'gm')
          tempMsg = tempMsg.replace(reg, `<span class="highlight" data-name="topic" data-params="name" data-value="${name}">${tag}</span>`)
        }
      }

      // 替换投票
      if (this.votes) {
        const { desc } = this.votes
        const voteId = this.votes.vote_id
        const voteReg = new RegExp(desc, 'gm')
        tempMsg = tempMsg.replace(voteReg, `<span class="highlight vote" data-name="vote" data-params="vid" data-value="${voteId}">${desc}</span>`)
      }

      // 替换表情
      if (emojis.length) {
        for (const emoji of emojis) {
          const emojiName = emoji.emoji_name
          const emojiUrl = emoji.url
          const emojiTag = emojiName.replace('[', '\\[').replace(/_/g, '\\_').replace(']', '\\]')
          const emojiReg = new RegExp(emojiTag, 'gm')
          tempMsg = tempMsg.replace(emojiReg, `<img src="${emojiUrl}" style="vertical-align:middle" width="22" height="22" alt="${name}" />`)
        }
      }
      tempMsg = tempMsg.replace(/\n/g, '<br>')
      // 替换网址
      tempMsg = tempMsg.replace(this.urlReg, '<a class="url" href="$1" target="_blank">网页链接</a>')
      return tempMsg
    }
  },
  mounted () {
    this.enableExpand = this.$refs.msg.scrollHeight > this.$refs.msg.clientHeight
  },
  methods: {
    toggle () {
      this.expand = !this.expand
    },
    redirect (e) {
      const target = e.target
      const tag = target.tagName.toLowerCase()
      if (tag === 'span') {
        const { name, params, value } = target.dataset
        name && this.rootRouter.push({ name, params: { [params]: value } })
      }
    }
  }
}
</script>

<style lang="scss">
  .msg {
    .url,
    .vote,
    .lottery{
       &::before {
        content: '';
        display: inline-block;
        vertical-align: top;
        width: rem(20px);
        height: rem(20px);
        background: {
          size: cover;
          position: center;
          repeat: no-repeat;
        }
       }
    }

    .url {
      color: $color-primary;
      &::before {
        background: {
          image: url('~@/assets/link.png')
        }
      }
    }
    .highlight {
      color: $color-primary;
    }
    .vote{
      &::before {
         background: {
          image: url('~@/assets/vote.png')
        }
      }
    }
    .lottery{
      &::before {
         background: {
          image: url('~@/assets/lottery.png')
        }
      }
    }
  }
</style>
<style lang="scss" scoped>
  .msg{
    padding: {
      left: rem(10px);
      right: rem(10px);
    }
    margin-bottom: rem(10px);
  }
  .content{
    position: relative;
    word-break: break-all;
    word-wrap: break-word;
    font-size: rem(16px);
    line-height: rem(23px);
    vertical-align: top;
  }
  .text {
    max-height: rem(92px);
    @include max-lines(4);
    &-expand {
      white-space: pre-wrap;
      vertical-align: top;
    }
  }
  .btn {
    color: $color-primary;
  }
</style>
